package com.shopping.service.trade;

import com.alibaba.fastjson.JSONObject;
import com.shopping.constant.ResponseCode;
import com.shopping.dao.*;
import com.shopping.pojo.*;
import com.shopping.pojo.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class TradeServiceImpl implements TradeService {

    @Autowired
    TradeDao tradeDao;
    @Autowired
    OrderDao orderDao;
    @Autowired
    AppraiseDao appraiseDao;
    @Autowired
    ShoppingCartDao shoppingCartDao;
    @Autowired
    CollectionDao collectionDao;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    JSONObject json = new JSONObject();

    @Override
    public Map<String, Object> addTrade(Trade trade) {
        Map<String, Object> map = new HashMap<>();
        try{
//            trade.setTradeName(DetectMarksUtil.replaceMarks(trade.getTradeName()));
//            trade.setTradeIntroduce(DetectMarksUtil.replaceMarks(trade.getTradeIntroduce()));
//            trade.setType1(DetectMarksUtil.replaceMarks(trade.getType1()));
//            trade.setType2(DetectMarksUtil.replaceMarks(trade.getType2()));
//            trade.setSpecification(DetectMarksUtil.replaceMarks(trade.getSpecification()));
            List<Trade> selectTrades = tradeDao.selectByStoreAndTradeName(trade.getStoreId(), trade.getTradeName());
            if(selectTrades.size() != 0){
                for(Trade t: selectTrades){
                    if(t.getSpecification().equals(trade.getSpecification())){
                        map.put("code", ResponseCode.ENTITY_ALREADY_EXISTS.getValue());
                        return map;
                    }
                }
            }
            tradeDao.insert(trade);
            int tradeId = tradeDao.lastInsertId();
            List<Trade> tradeList = json.parseArray(stringRedisTemplate.opsForValue().get("trade" + trade.getStoreId()), Trade.class);
            if(tradeList == null){
                tradeList = new ArrayList<>();
            }
            trade.setId(tradeId);
            tradeList.add(trade);
            stringRedisTemplate.opsForValue().set("trade" + trade.getStoreId(), json.toJSONString(tradeList));
            trade.setId(tradeId);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
            map.put("trade", trade);
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> outOfStock(int tradeId) {
        Map<String, Object> map = new HashMap<>();
        try{
            Trade trade = tradeDao.selectById(tradeId);
            tradeDao.deleteTrade(tradeId);
            List<Trade> tradeList = json.parseArray(stringRedisTemplate.opsForValue().get("trade" + trade.getStoreId()), Trade.class);
            if(tradeList != null){
                tradeList.remove(trade);
            }
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
            stringRedisTemplate.opsForValue().set("trade" + trade.getStoreId(), json.toJSONString(tradeList));
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> showTradeMessageById(int id) {
        Map<String, Object> map = new HashMap<>();
        try{
            Trade trade = null;
            Integer storeId = tradeDao.selectStoreIdById(id);
            if(storeId == null){
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
                return map;
            }
            List<Trade> tradeList = json.parseArray(stringRedisTemplate.opsForValue().get("trade" + storeId), Trade.class);
            for(Trade t: tradeList){
                if(t.getId() == id){
                    trade = t;
                    break;
                }
            }
            if(trade == null){
                trade = tradeDao.selectById(id);
            }
            if(trade != null){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("trade", trade);
            }else{
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            }
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> showTradeMessageByStoreAndTradeName(int storeId, String tradeName) {
        Map<String, Object> map = new HashMap<>();
        try{
//            tradeName = DetectMarksUtil.replaceMarks(tradeName);
            List<Trade> tradeList = json.parseArray(stringRedisTemplate.opsForValue().get("trade" + storeId), Trade.class);
            List<Trade> showList = new ArrayList<>();
            for(Trade t: tradeList){
                if(t.getTradeName().equals(tradeName)){
                    showList.add(t);
                }
            }
//            List<Trade> trades = tradeDao.selectByStoreAndTradeName(storeId, tradeName);
            if(showList.size() != 0){
                map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
                map.put("trade", showList);
            }else{
                map.put("code", ResponseCode.ENTITY_NOT_EXISTS.getValue());
            }
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> addAppraise(Appraise appraise) {
        Map<String, Object> map = new HashMap<>();
        try{
//            appraise.setAppraiseContent(DetectMarksUtil.replaceMarks(appraise.getAppraiseContent()));
            appraiseDao.insertAppraise(appraise);
            int appraiseId = appraiseDao.lastInsertId();
            appraise.setId(appraiseId);
            orderDao.updateAppraise(appraiseId, appraise.getStoreId(), appraise.getTradeId(), appraise.getUserId());
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
            map.put("appraise", appraise);
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> addFans(int tradeId, int fansId) {
        Map<String, Object> map = new HashMap<>();
        try{
            Collection collection = new Collection();
            collection.setType(2);
            collection.setId(tradeId);
            collection.setUserId(fansId);
            collectionDao.insert(collection);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> addShoppingCart(ShoppingCart shoppingCart) {
        Map<String, Object> map = new HashMap<>();
        try{
            Trade trade = tradeDao.selectById(shoppingCart.getTradeId());
            if(trade.getInventory() < shoppingCart.getNumber()){
                map.put("code", ResponseCode.PARAM_ERROR.getValue());
                return map;
            }
            shoppingCartDao.insert(shoppingCart);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> increaseInventory(int tradeId, int addNum) {
        Map<String, Object> map = new HashMap<>();
        try{
            tradeDao.increaseInventory(tradeId, addNum);
            int storeId = tradeDao.selectById(tradeId).getStoreId();
            List<Trade> tradeList = json.parseArray(stringRedisTemplate.opsForValue().get("trade" + storeId), Trade.class);
            Trade trade = null;
            for(Trade t: tradeList){
                if(t.getId() == tradeId){
                    t.setInventory(t.getInventory() + addNum);
                    trade = t;
                    break;
                }
            }
            stringRedisTemplate.opsForValue().set("trade" + storeId, json.toJSONString(tradeList));
            if(trade == null){
                trade = tradeDao.selectById(tradeId);
            }
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
            map.put("trade", trade);
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> buyTrade(Order order) {
        Map<String, Object> map = new HashMap<>();
        try{
            int inventory = -1;
            List<Trade> tradeList = json.parseArray(stringRedisTemplate.opsForValue().get("trade" + order.getStoreId()), Trade.class);
            for(Trade t: tradeList){
                if(t.getId() == order.getTradeId()){
                    inventory = t.getInventory();
                    if(inventory > order.getNumber()){
                        t.setInventory(inventory - order.getNumber());
                    }
                    break;
                }
            }
            if(inventory == -1){
                inventory = tradeDao.selectInventory(order.getTradeId());
            }
            if(inventory < order.getNumber()){
                map.put("code", ResponseCode.INVENTORY_SHORTAGE.getValue());
                return map;
            }
            tradeDao.updateInventory(order.getTradeId());
            stringRedisTemplate.opsForValue().set("trade" + order.getStoreId(), json.toJSONString(tradeList));
            orderDao.insert(order);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
        }catch (Exception e){
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public Map<String, Object> showTypes() {
        Map<String, Object> map = new HashMap<>();
        try {
            Set<String> type1s = tradeDao.selectType();
            List<TradeType> tradeTypes = new ArrayList<>();
            for(String s: type1s){
                Set<String> type2s = tradeDao.selectTypeByType(s);
                tradeTypes.add(new TradeType(s, type2s));
            }
            map.put("tradeTypes", tradeTypes);
            map.put("code", ResponseCode.REQUEST_SUCCESSED.getValue());
        }catch (Exception e){
            e.printStackTrace();
            map.put("code", ResponseCode.SERVER_ERROR.getValue());
        }
        return map;
    }

}
